import React, { memo, useCallback, useEffect, useRef, useState } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';

import {
  getSongDetailAction,
  changeSequenceAction,
  changeCurrentIndexSongAction,
  changeCurrentLyricsIndexAction
} from '../store/actionCreators';
import {
  getSizeImage,
  formatMinuteSecond,
  getPlayUrl
} from 'utils/format-util'


import { message } from 'antd';
import { NavLink } from 'react-router-dom';
import { Slider } from 'antd';
import {
  PlaybarWrapper,
  Control,
  PlayInfo,
  Operator
} from './style'

const MXAppPlayerBar = memo(() => {
  // props and state
  const [currentTime, setCurrentTime] = useState(0)
  const [progress, setProgress] = useState(0)
  const [isChanging, setIsChanging] = useState(false)
  const [isPlaying, setIsPlaying] = useState(false)

  // redux hooks
  const {
    currentSong,
    sequence,
    lyricsList,
    currentLyricsIndex
  } = useSelector(state => ({
    currentSong: state.getIn(['player', 'currentSong']),
    sequence: state.getIn(['player', 'sequence']),
    lyricsList: state.getIn(['player', 'lyricsList']),
    currentLyricsIndex: state.getIn(['player', 'currentLyricsIndex'])
  }), shallowEqual)

  const dispatch = useDispatch()

  //other hooks
  const audioRef = useRef()
  useEffect(() => {
    dispatch(getSongDetailAction(167876))
  }, [dispatch])
  useEffect(() => {
    audioRef.current.src = getPlayUrl(currentSong.id)
    audioRef.current.play().then(res => {
      setIsPlaying(true)
    }).catch(err => {
      setIsPlaying(false)
    })
  }, [currentSong])

  // other hande
  const picUrl = (currentSong.al && currentSong.al.picUrl) || ''
  const singerName = (currentSong.ar && currentSong.ar[0].name) || '未知歌手'
  const duration = currentSong.dt || 0
  const showCurrentTime = formatMinuteSecond(currentTime)

  // handle function
  const playMusic = useCallback(() => {
    setIsPlaying(!isPlaying)
    isPlaying ? audioRef.current.pause() : audioRef.current.play()
  }, [isPlaying])

  const timeUpdate = (e) => {
    const currentTime = e.target.currentTime * 1000
    if(!isChanging) {
      setCurrentTime(currentTime)
      setProgress(currentTime / duration * 100)
    }

    // 获取当前歌词
    let i = 0
    for(; i < lyricsList.length; i++) {
      let lyricsItem = lyricsList[i]
      if(currentTime < lyricsItem.time) {
        break;
      }
    }
    if(currentLyricsIndex !== i - 1) {
      dispatch(changeCurrentLyricsIndexAction(i - 1))
      const content = lyricsList[i - 1] && lyricsList[i - 1].content
      if(!content) return
      message.open({
        key: lyricsList,
        content,
        duration: 0,
        className: 'lyric-class'
      })
    }
  }

  const changeSequence = () => {
    let currentSequence = sequence + 1
    if(currentSequence > 2) {
      currentSequence = 0
    }
    dispatch(changeSequenceAction(currentSequence))
  }

  const changeMusic = (tag) => {
    dispatch(changeCurrentIndexSongAction(tag))
  }

  const handleMusicEnded = () => {
    if(sequence === 2) {
      audioRef.current.currentTime = 0
      audioRef.current.play()
    } else {
      dispatch(changeCurrentIndexSongAction(1))
    }
  }

  const sliderChange = useCallback(
    (value) => {
      setIsChanging(true)
      const currentTime = value / 100 * duration
      setCurrentTime(currentTime)
      setProgress(value)
    },
    [duration],
  )

  const sliderAfterChange = useCallback(
    (value) => {
      const currentTime = value / 100 *  duration / 1000
      audioRef.current.currentTime = currentTime
      setCurrentTime(currentTime * 1000)
      setIsChanging(false)

      if(!isPlaying) {
        playMusic()
      }
    },
    [duration, isPlaying, playMusic]
  )

  return (
    <PlaybarWrapper className="sprite_playbar">
      <div className="content wrap-v2">
        <Control isPlaying={isPlaying}>
          <button className="sprite_playbar btn prev"
              onClick={e => changeMusic(-1)}/>
          <button className="sprite_playbar btn play"
              onClick={e => playMusic()}/>
          <button className="sprite_playbar btn next"
              onClick={e => changeMusic(1)}/>
        </Control>
        <PlayInfo>
          <div className="image">
            <NavLink to="/discover/player">
              <img src={getSizeImage(picUrl, 35)} alt="" />
            </NavLink>
          </div>
          <div className="info">
            <div className="song">
              <span className="song-name">{currentSong.name}</span>
              <a href="/#" className="singer-name">{singerName}</a>
            </div>
            <div className="progress">
              <Slider
                  value={progress}
                  onChange={sliderChange}
                  onAfterChange={sliderAfterChange}/>
              <div className="time">
                <span className="now-time">{showCurrentTime}</span>
                <span className="divider">/</span>
                <span className="duration">{formatMinuteSecond(duration)}</span>
              </div>
            </div>
          </div>
        </PlayInfo>
        <Operator sequence={sequence}>
          <div className="left">
            <button className="sprite_playbar btn favor"></button>
            <button className="sprite_playbar btn share"></button>
          </div>
          <div className="right sprite_playbar">
            <button className="sprite_playbar btn volume"></button>
            <button className="sprite_playbar btn loop" onClick={e => changeSequence()}></button>
            <button className="sprite_playbar btn playlist" ></button>
          </div>
        </Operator>
      </div>
      <audio ref={audioRef}
          onTimeUpdate={e => timeUpdate(e)}
          onEnded={e => handleMusicEnded()}/>
    </PlaybarWrapper>
  );
});

export default MXAppPlayerBar;